const { ccclass, property } = cc._decorator;

@ccclass
export default class MgrAudio extends cc.Component {

    @property({ min: 0, max: 1 })
    volGlobal: number = 1;
    @property({ min: 0, max: 1 })
    volBGM: number = 1;
    @property(cc.AudioClip)
    s_BGM: cc.AudioClip = null;
    @property({ type: [cc.AudioClip] })
    s_audios: cc.AudioClip[] = [];

    static Instance: MgrAudio = null;

    musicBG: cc.AudioSource = new cc.AudioSource();
    voiceOver: cc.AudioSource = new cc.AudioSource();
    mapMusic: Map<number, cc.AudioSource> = new Map();
    loopMusic: Map<number, cc.AudioSource> = new Map();

    onLoad() {
        MgrAudio.Instance = this;
    }

    start() {
        this.musicBG.clip = this.s_BGM;
        this.musicBG.node = this.node;
        this.voiceOver.node = this.node;
        this.s_audios.forEach((v, k) => {
            let tAu = new cc.AudioSource();
            tAu.node = this.node;
            tAu.clip = this.s_audios[k];
            this.mapMusic.set(k, tAu);
        })
    }

    PlayBGMusic() {
        if (!this.musicBG.isPlaying) {
            this.musicBG.play();
            this.musicBG.volume = this.volBGM * this.volGlobal;
            this.musicBG.loop = true;
        }
    }

    StopBGMusic() {
        if (this.musicBG.isPlaying) {
            this.musicBG.stop();
        }
    }

    PlayMusic(index: number, loop: boolean = false, volume: number = 1, checkPlaying: boolean = false) {
        let tAu = this.mapMusic.get(index);
        if (!checkPlaying || !tAu.isPlaying) {
            tAu.loop = loop;
            tAu.volume = volume * this.volGlobal;
            tAu.play();
        }
    }

    StopMusic(index: number, loop: boolean = false) {
        let tAu = this.mapMusic.get(index);
        tAu.loop = loop;
        tAu.stop();
    }

    StopLoopingMusic(index: number) {
        this.mapMusic.get(index).stop();
        this.mapMusic.get(index).loop = false;
    }

    StopMutipMusic(index: number) {
        if (this.loopMusic.has(index)) {
            let tAu = this.loopMusic.get(index);
            tAu.stop();
        }
    }

    GetAudioByName(name: number) {
        if (this.mapMusic.has(name)) {
            return this.mapMusic.get(name);
        }
        return null;
    }

    StopAll() {
        this.StopBGMusic();
        this.voiceOver.stop();
        this.mapMusic.forEach((v) => {
            v.stop();
        })
        this.loopMusic.forEach((v) => {
            v.stop();
        })
    }

    forcePlayMusic(index: number, loop: boolean = false, volume: number = 1, destroyDelay: number = 1) {
        let tAu = this.mapMusic.get(index);
        if (tAu.isPlaying) {
            let tmpAuNode = new cc.Node("tmpAuNode");
            tAu.node.parent.addChild(tmpAuNode);
            let tmpAu = tmpAuNode.addComponent(cc.AudioSource);
            tmpAu.clip = tAu.clip;
            tmpAu.loop = loop;
            tmpAu.volume = volume * this.volGlobal;
            tmpAu.play();
            this.scheduleOnce(() => { tmpAuNode.destroy() }, destroyDelay);
        } else this.PlayMusic(index, loop, volume);
    }
}
